package cn.uce.job.srv.biz.impl;

import cn.uce.base.entity.CcSmsRecord;
import cn.uce.base.vo.CcRpCallAllDateVo;
import cn.uce.base.vo.CcSmsRecordVo;
import cn.uce.cc.api.service.biz.ICcSmsMessageBiz;
import cn.uce.cc.srv.utils.HttpClientUtil;
import cn.uce.common.constants.CcConstants;
import cn.uce.common.omg.biz.IOmgOrgBiz;
import cn.uce.common.omg.dao.impl.ICsFspDictDateDao;
import cn.uce.ics.base.entity.cs.IcsFspDictDataEntity;
import cn.uce.ics.base.entity.cs.RpCallalldata;
import cn.uce.ics.base.vo.srv.IcsRpCallalldataVo;
import cn.uce.ics.base.vo.srv.postal.PotevioTeleReceiveRateReq;
import cn.uce.job.api.service.biz.IRpCallalldataBiz;
import cn.uce.job.entity.OpenChannelInfoReq;
import cn.uce.job.srv.servce.RpCallalldataService;
import cn.uce.utils.StringUtil;
import cn.uce.web.common.base.CurrentUser;
import cn.uce.web.common.util.DateUtil;
import cn.uce.web.common.util.WebUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.*;

/**
 * @Description: BIZ实现类
 * @author UCE-CodeGenerator
 * @date 2019年10月28日 下午02:09:12
 */
@Service("rpCallalldataBiz")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class RpCallalldataBiz implements IRpCallalldataBiz {
	private Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 注入Service
	 */
	@Resource
	private RpCallalldataService rpCallalldataService;

	@Resource
	private ICcSmsMessageBiz ccSmsMessageBiz;

	@Resource
	private ICsFspDictDateDao csFspDictDateDao;

	@Resource
	private IOmgOrgBiz omgOrgBiz;

	@Autowired
	private JobParmaUitl jobParmaUitl;


	/**
	 * @Description: 新增
	 * @param rpCallalldata
	 * @return 受影响行数
	 * @author UCE-CodeGenerator
	 * @date 2019年10月28日 下午02:09:12
	 */
	@Override
	public int addRpCallalldata(RpCallalldata rpCallalldata) {
		return rpCallalldataService.addRpCallalldata(rpCallalldata);
	}
	
	/**
	 * @Description: 修改
	 * @param rpCallalldata 
	 * @return 受影响行数
	 * @author UCE-CodeGenerator
	 * @date 2019年10月28日 下午02:09:12
	 */
	@Override
	public int updateRpCallalldata(RpCallalldata rpCallalldata) {
		return rpCallalldataService.updateById(rpCallalldata);
	}
	
	/**
	 * @Description: 删除
	 * @param id 主键
	 * @return 受影响行数
	 * @author UCE-CodeGenerator
	 * @date 2019年10月28日 下午02:09:12
	 */
	@Override
	public int deleteRpCallalldata(Long id) {
		return rpCallalldataService.deleteById(id);
	}
	
	/**
	 * @Description: 根据ID查询
	 * @param id 主键
	 * @return 
	 * @author UCE-CodeGenerator
	 * @date 2019年10月28日 下午02:09:12
	 */
	@Override
	public RpCallalldata findById(Long id) {
		return rpCallalldataService.findById(id);
	}
	


	/**
	 * @Description: 分页查询
	 * @param rateReq
	 * @return
	 * @author UCE-CodeGenerator
	 * @date 2019年10月28日 下午02:09:12
	 */
	@Override
	public List<PotevioTeleReceiveRateReq> findByList(PotevioTeleReceiveRateReq rateReq){
		List<PotevioTeleReceiveRateReq> data = rpCallalldataService.findByList(rateReq);
		return data.get(0) == null ? new ArrayList<PotevioTeleReceiveRateReq>(0) :data;
	}

	/**
	 * 查话务数据库
	 * 1.取模查本地库最大ID
	 * 2.查oracle库>本地最大时间的数据
	 * @param rateReq
	 * @return
	 */
	@Override
	public List<RpCallalldata> findOrcaleByList(PotevioTeleReceiveRateReq rateReq){
		return rpCallalldataService.findOrcaleByList(rateReq);
	}



	@Override
	public int insert(RpCallalldata req) {
		return 0;
	}

	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public int insert(List<RpCallalldata> reqs, Map<String,Object> map) {
		int i =0;
		for (RpCallalldata rpCallalldata : reqs){
			try {
				rpCallalldataService.insert(rpCallalldata);
				map.put("lastTime",DateFormatUtils.format(rpCallalldata.getOffhktm(),DateUtil.DATE_PATTERN.YYYY_MM_DD_HH_MM_SS));
				i++;
			}catch (Exception e){
				logger.warn("话务同步失败callid={}",reqs.get(i).getCallid(),e);
			}
		}
		//没有新数据，时间+1秒
		logger.warn("话务同步{}，实际同步{}条",reqs.size(),i);
		return  i;
	}

	@Override
	public String findByMaxTime(PotevioTeleReceiveRateReq rateReq){
		return rpCallalldataService.findByMaxTime(rateReq);
	}

	@Override
	public List<RpCallalldata> findNeedSendMessageList(CcRpCallAllDateVo vo) {
		return rpCallalldataService.findNeedSendMessageList(vo);
	}

	 /**
	  * 校验短信是否发送过,然后拿到url进行短信拼接
	   * @Author liupan
	   * @Description 
	   * @Date  2020-06-15 11:24
	  * @param reqs
	   */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void pushMessage(List<RpCallalldata> reqs) {
		if (reqs != null && !reqs.isEmpty()) {
			for (RpCallalldata req : reqs) {
				CcSmsRecordVo queryVo = new CcSmsRecordVo();
				queryVo.setBillCode(String.valueOf(req.getCallid()));
				queryVo.setMoblileNum(req.getAni());
				CcSmsRecord billCodeAndPhoneNum = ccSmsMessageBiz.findBillCodeAndPhoneNum(queryVo);
				if (billCodeAndPhoneNum ==null){
					String urlForPhoneNum = getUrlForPhoneNum(req.getAni(), String.valueOf(req.getCallid()));
					sendMessage(urlForPhoneNum,req.getAni(),String.valueOf(req.getCallid()));
					rpCallalldataService.updateDeleteFlagById(req);
				}
			}
		}
	}

	/**
	 *
	 * @param url 要拼装的参数
	 * @param phoneNum 要接受的手机号
	 * @param callId
	 */
	public void sendMessage(String url,String phoneNum,String callId){
		CcSmsRecord ccSmsRecord = new CcSmsRecord();
		ccSmsRecord.setCreateOrgCode(omgOrgBiz.getHqOrgCode());
		ccSmsRecord.setMoblileNum(phoneNum);
		ccSmsRecord.setBillCode(callId);
		ccSmsRecord.setContext(url);
		ccSmsRecord.setPayOrgCode(omgOrgBiz.getHqOrgCode());
		ccSmsRecord.setCreateEmp("CC系统");
		ccSmsRecord.setTemplateCode(CcConstants.TEMPLATE_SATISFIED_MESSAGE);
		ccSmsRecord.setProblemTypeName(CcConstants.TEMPLATE_SATISFIED_MESSAGE);
		ccSmsMessageBiz.sendMessage(ccSmsRecord);
		logger.warn("sendMessage:"+ JSON.toJSONString(ccSmsRecord));
	}



	public IcsFspDictDataEntity findDictDate(String typeClassCode, String typeCode) {
		IcsFspDictDataEntity vo  = new IcsFspDictDataEntity();
		vo.setTypeClassCode(typeClassCode);
		vo.setTypeCode(typeCode);
		IcsFspDictDataEntity  fspData =  csFspDictDateDao.findByClassCode(vo);
		return fspData;
	}


	/**
	 * 获取同步3d呼叫数据的开关
	 * @return
	 */
	@Override
	public boolean getThirdDbToCcDbSwitch() {
		List<IcsFspDictDataEntity> fspDate = csFspDictDateDao.findByClass(CcConstants.GET_THIRDDDB_TO_CC_DB_SWITCH);
		if (fspDate != null && fspDate.size() > 0) {
			if (StringUtil.isNotEmpty(fspDate.get(0).getTypeCode())) {
				return CcConstants.CHECK_BILLCODE_SWITCH_TRUE.equals(fspDate.get(0).getTypeCode());
			}
		}
		return false;
	}

	/**
	 * 发送满意度短信开关
	 * @return
	 */
	@Override
	public boolean getSatisFiedMessageSwtich() {
		List<IcsFspDictDataEntity> fspDate = csFspDictDateDao.findByClass(CcConstants.SATISFIED_MESSAGE_SWTICH);
		if (fspDate != null && fspDate.size() > 0) {
			if (StringUtil.isNotEmpty(fspDate.get(0).getTypeCode())) {
				return CcConstants.CHECK_BILLCODE_SWITCH_TRUE.equals(fspDate.get(0).getTypeCode());
			}
		}
		return false;
	}

	 /**
	  * 根据手机号获取路径
	   * @Author liupan
	   * @Description
	   * @Date  2020-06-15 13:43
	   */
	public  String getUrlForPhoneNum(String phoneNum, String callId){
		//开启使用新方法
		String returnrul = null;
		boolean aswitch = getUrlForPhoneNumSwitch();
		if (aswitch){
			returnrul = getUrlForPhoneNumNew(phoneNum,callId);
			logger.warn("getUrlForPhoneNum,switch"+aswitch+",url:"+returnrul);
			return returnrul;
		}else{
			returnrul = getUrlForPhoneNumOld(phoneNum,callId);
			logger.warn("getUrlForPhoneNum,switch"+aswitch+",url:"+returnrul);
			return returnrul;
		}
	}



	 /**
	   * 根据手机号和callid去ccim查询链接,走内网,无加密
	  * 开关
	   * @Author liupan
	   * @Description
	   * @Date  2020-07-13 10:53
	   */
	public boolean getUrlForPhoneNumSwitch() {
		List<IcsFspDictDataEntity> fspDate = csFspDictDateDao.findByClass(CcConstants.CCIM_GET_SATISFIED_SWITCH);
		if (fspDate != null && fspDate.size() > 0) {
			if (StringUtil.isNotEmpty(fspDate.get(0).getTypeCode())) {
				return CcConstants.CHECK_BILLCODE_SWITCH_TRUE.equals(fspDate.get(0).getTypeCode());
			}
		}
		return false;
	}


	/**
	 * 根据手机号和callid去ccim查询链接,走内网,有md5加密
	 * @Author liupan
	 * @Description
	 * @Date  2020-07-13 10:51
	 */
	public String getUrlForPhoneNumNew(String phoneNum, String callId){
		JSONObject jsonObject = new JSONObject();

		String map = null;
		try {
			jsonObject.put("number", callId);
			jsonObject.put("channel", CcConstants.CC_CHANNEL);
			jsonObject.put("phone", phoneNum);
			jsonObject.put("voiceLink", null);
			OpenChannelInfoReq openChannelInfo = new OpenChannelInfoReq();
			openChannelInfo.setChannel( CcConstants.CC_CHANNEL);
			openChannelInfo.setNumber(callId);
			openChannelInfo.setPhone(phoneNum);
			openChannelInfo.setVoiceLink(null);
			String md5Str = md5(openChannelInfo, jobParmaUitl.getCcimMssageKey());
			openChannelInfo.setSign(md5Str);
			jsonObject.put("sign",md5Str);
			String url = findDictDate(CcConstants.CCIM_GET_SATISFIED_HOST,"0").getTypeName() + CcConstants.CCIM_GET_SATISFIED_URL;
			map = HttpClientUtil.doPostJson(
					url,
					jsonObject, true);
			if (StringUtil.isNotEmpty(map)) {
				Map<String, Object> reMap = JSONObject.parseObject(map);
				if (reMap != null && !reMap.isEmpty() && reMap.get("code").equals("0")) {
					logger.warn("getUrlForPhoneNum,map:"+map+",phoneNum:"+phoneNum+",callId:"+callId);
					return String.valueOf(reMap.get("msg"));
				}
			}
		} catch (Exception e) {
			logger.warn("getUrlForPhoneNum,reqs.size()",e);
		}

		return null;
	}

	private static String md5(Object o, String secretKey) {
		Method[] methods = o.getClass().getMethods();
		List<String> keyLists = Lists.newArrayList();
		HashMap<String, String> paramsMap = Maps.newHashMap();
		for (Method method : methods) {
			if (StringUtils.startsWith(method.getName(), "get") && !StringUtils.equals(method.getName(), "getSign") && method.getParameterTypes().length == 0 && !method.getName().contains("Class")) {
				try {
					String key = StringUtils.uncapitalize(StringUtils.removeStart(method.getName(), "get"));
					String value = JSONObject.toJSONString(method.invoke(o));
					if (StringUtils.isBlank(value)) {
						continue;
					}
					keyLists.add(key);
					paramsMap.put(key, value);
				} catch (IllegalAccessException | InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		Collections.sort(keyLists);
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0, size = keyLists.size(); i < size; i++) {
			String key = keyLists.get(i);
			stringBuilder.append(key).append("=").append(paramsMap.get(key));
			stringBuilder.append("&");
			if (i == size - 1) {
				stringBuilder.append("secretKey=").append(secretKey);
			}
		}
		return DigestUtils.md5Hex(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
	}

	 /**
	   * 根据手机号和callid去ccim查询链接,走内网,无加密
	   * @Author liupan
	   * @Description
	   * @Date  2020-07-13 10:51
	   */
	public String getUrlForPhoneNumOld(String phoneNum, String callId){
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("number", callId);
		jsonObject.put("channel", CcConstants.CC_CHANNEL);
		jsonObject.put("phone", phoneNum);
		jsonObject.put("voiceLink", null);
		String map = null;
		try {
			String url = findDictDate(CcConstants.CCIM_GET_SATISFIED_HOST,"0").getTypeName() + CcConstants.CCIM_GET_SATISFIED_URL;
			map = HttpClientUtil.doPostJson(
					url,
					jsonObject, true);
			if (StringUtil.isNotEmpty(map)) {
				Map<String, Object> reMap = JSONObject.parseObject(map);
				if (reMap != null && !reMap.isEmpty() && reMap.get("code").equals("0")) {
					logger.warn("getUrlForPhoneNum,map:"+map+",phoneNum:"+phoneNum+",callId:"+callId);
					return String.valueOf(reMap.get("msg"));
				}
			}
		} catch (Exception e) {
			logger.warn("getUrlForPhoneNum,reqs.size()",e);
		}

		return null;
	}


//	public static void main(String[] args) {
//		String urlForPhoneNum = getUrlForPhoneNumOldNew("13923558670", "792630000271374");
//		System.out.println(urlForPhoneNum);
//	}
}